Binary Search is one of the most common techniques being used in scenarios of searching. It has many types of variants and I would like to discuss some of it and why the edge cases are designed like this.
1.Search for a element in array (familiar)
This is probably the most common way to use binary search. It involves finding mid point within a range and thus divides the range (smaller the search range) based on the midpoint. Common implementation is:
1 | int binarySearch(int[] nums, int target) { |
Some important value includes: value of initial right, different value assignment in three different cases (less than, larger than, or equal to), and the criterion of while loop (< or <= ?).
value of right: By assigning “nums.length - 1”, we means that we are searching in range [left, right] (right boundary inclusive).If “nums.length”, then we are saying [left, right) (right boundary inclusive)
while loop criterion (< or <=) : By assigning <, we should jump out of the loop when left == right, which means that [left, right] will results in a omitted value, and [left, right) will not omit. Therefore when we pick the criterion, we should adjust the initial value of right accordingly to avoid unexpected behavior.
In short: (right = nums.length - 1, then while <=), (right = nums.length, then while <)
Different cases for <, > , ==: The value assignment for different case really depends on what you would like to find
Find index of a element (value may have duplicate, so random occurrence): < : left = mid + 1, >:right = mid - 1, == : return mid;
Find index of the left boundary (first occurrence) of a element:
< : left = mid + 1, >:right = mid - 1, == : right = mid - 1 (narrow the right boundary to finally get the left bound);
- Find index of the right boundary (last occurrence) of a element:
< : left = mid + 1, >:right = mid - 1, == : left = mid + 1 (narrow the left boundary to finally get the right bound);
2.Search for boundary in a array (first or last occurrence)
When find left bound or right bound, be careful of indexOutBoundary error when the target element is bigger/smaller than all elements in array. In that case, right value will be left - 1/left value be right +1. For example, when we end up with range such as [9(left), 8(right)], apparently, it is not reasonable to take left bound 9 as our final left bound since the range contain no value. So, make sure we check for rationality at the end.
1 | // Finally, after while loop, check Out of Boundary error |
To Wrap this up, we have three different implementation template for finding index, first occurrence (left bound) ,and last occurrence(right bound) as follows:
1 | // To keep consistency, we use nums.length - 1 for right, and <= criterion in while loop |
Besides my provided templates, there are many different implementations, some embedded condition checked edition are like:
1 | int left_bound(int[] nums, int target) { |
- 本文作者: Yu Wan
- 本文链接: https://cyanh1ll.github.io/2021/01/11/Binary Search tips/
- 版权声明: CYANH1LL